/**
 * file :	wa_exception.h
 * author :	bushaofeng
 * created :	2013-03-11 20:18
 * func : 
 */

#ifndef	__WA_EXCEPTION_H_
#define	__WA_EXCEPTION_H_

#include <iostream>
#include "wa_define.h"

using namespace std;

// throw error
#define WA_ERR_USER_PASSERR     "用户名或密码错误"
#define WA_ERR_USER_NOTFOUND    "用户不存在"
#define WA_ERR_USER_PASSWARD    "密码错误"
#define WA_ERR_USER_DUP         "用户名已存在"

#define WA_ERR_FIELD_NOTFOUND   "缺少必须字段"

#define WA_ERR_PROJ_DUP         "项目已存在"
#define WA_ERR_PROJ_NOTFOUND    "项目不存在"

#define WA_ERR_DEFAULT          "未知错误"
#define WA_ERR_SYSTEM           "系统错误"

enum{
    WA_ERR_DEF,
    WA_ERR_USER,
    WA_ERR_PROJ,
    WA_ERR_FIELD,
    WA_ERR_NUM
};

enum{
    // 直接将错误发送客户端
    WA_ERR_LEVEL_PUBLIC,
    // 不能发送客户端的错误
    WA_ERR_LEVEL_PRIVATE,
};

class WAException:public string{
    public:
        /**
         * 单独用code无法区别错误类型，比如dup错误可能属于不同的表，返回的错误也要不一样
         * type: 错误类别，比如是属于user的错误还是project的错误
         * level: 错误级别，是否可以共享给客户端。例如创建对象失败等错误，不能共享给客户端
         */
        WAException(int type, int code, int level = WA_ERR_LEVEL_PUBLIC){
            *this = getMongoError(type, code);

            if(level != WA_ERR_LEVEL_PUBLIC){
                m_out_err = WA_ERR_SYSTEM;
            }

            m_code = code;
            m_type = type;
            m_level = level;
        }

        WAException(const char* err, int level = WA_ERR_LEVEL_PUBLIC):string(err){
            m_out_err = err;
            if(level != WA_ERR_LEVEL_PUBLIC){
                m_out_err = WA_ERR_SYSTEM;
            }
        }

        const char* getMongoError(int type, int code);
        inline int getCode(){return m_code;}
        inline int getType(){return m_type;}

        const char* what(){
            return m_out_err;
        }
        const char* real(){
            return c_str();
        }

    private:
        int     m_type;
        int     m_code;
        int     m_level;
        const char*   m_out_err;
};

#endif
